{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "from sklearn import datasets\n",
    "from tensorflow.python.framework import ops\n",
    "ops.reset_default_graph()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "iris = datasets.load_iris()\n",
    "x_vals = np.array([x[0:3] for x in iris.data])\n",
    "y_vals = np.array([x[3] for x in iris.data])\n",
    "sess = tf.Session()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "seed = 3\n",
    "tf.set_random_seed(seed)\n",
    "np.random.seed(seed)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "train_indices = np.random.choice(len(x_vals), round(len(x_vals)*0.8), replace=False)\n",
    "test_indices = np.array(list(set(range(len(x_vals))) - set(train_indices)))\n",
    "x_vals_train = x_vals[train_indices]\n",
    "x_vals_test = x_vals[test_indices]\n",
    "y_vals_train = y_vals[train_indices]\n",
    "y_vals_test = y_vals[test_indices]\n",
    "def normalize_cols(m):\n",
    "    col_max = m.max(axis=0)\n",
    "    col_min = m.min(axis=0)\n",
    "    return (m-col_min) / (col_max - col_min)\n",
    "x_vals_train = np.nan_to_num(normalize_cols(x_vals_train))\n",
    "x_vals_test = np.nan_to_num(normalize_cols(x_vals_test))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "batch_size = 50\n",
    "x_data = tf.placeholder(shape=[None, 3], dtype=tf.float32)\n",
    "y_target = tf.placeholder(shape=[None, 1], dtype=tf.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "hidden_layer_nodes = 10\n",
    "A1 = tf.Variable(tf.random_normal(shape=[3,hidden_layer_nodes]))\n",
    "b1 = tf.Variable(tf.random_normal(shape=[hidden_layer_nodes]))\n",
    "A2 = tf.Variable(tf.random_normal(shape=[hidden_layer_nodes,1]))\n",
    "b2 = tf.Variable(tf.random_normal(shape=[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "hidden_output = tf.nn.relu(tf.add(tf.matmul(x_data, A1), b1))\n",
    "final_output = tf.nn.relu(tf.add(tf.matmul(hidden_output, A2), b2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "loss = tf.reduce_mean(tf.square(y_target - final_output))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "my_opt = tf.train.GradientDescentOptimizer(0.005)\n",
    "train_step = my_opt.minimize(loss)\n",
    "init = tf.global_variables_initializer()\n",
    "sess.run(init)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Generation: 50. Loss = 0.112982\n",
      "Generation: 100. Loss = 0.0784244\n",
      "Generation: 150. Loss = 0.0803005\n",
      "Generation: 200. Loss = 0.0675039\n",
      "Generation: 250. Loss = 0.0840415\n",
      "Generation: 300. Loss = 0.0661501\n",
      "Generation: 350. Loss = 0.0476385\n",
      "Generation: 400. Loss = 0.0914209\n",
      "Generation: 450. Loss = 0.0812059\n",
      "Generation: 500. Loss = 0.0842396\n"
     ]
    }
   ],
   "source": [
    "loss_vec = []\n",
    "test_loss = []\n",
    "for i in range(500):\n",
    "    rand_index = np.random.choice(len(x_vals_train), size=batch_size)\n",
    "    rand_x = x_vals_train[rand_index]\n",
    "    rand_y = np.transpose([y_vals_train[rand_index]])\n",
    "    sess.run(train_step, feed_dict={x_data: rand_x, y_target: rand_y})\n",
    "\n",
    "    temp_loss = sess.run(loss, feed_dict={x_data: rand_x, y_target: rand_y})\n",
    "    loss_vec.append(np.sqrt(temp_loss))\n",
    "\n",
    "    test_temp_loss = sess.run(loss, feed_dict={x_data: x_vals_test, y_target: np.transpose([y_vals_test])})\n",
    "    test_loss.append(np.sqrt(test_temp_loss))\n",
    "    if (i+1)%50==0:\n",
    "        print('Generation: ' + str(i+1) + '. Loss = ' + str(temp_loss))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\nZQpff/01f/nLX476HF62bt2KMSbsLtbHivN+nKgsX768RJ1KygsqCqXAV199xeTJkwF/Ubj33nsB\nGDNmTJHHT506FbBdOB955BH+8Ic/FMpTEk/BiWOLiBtSmjFjBs8++6ybt3379n5eDtgus507dy7S\nVi+HDh1yvyckJADw448/uvuceaD279/P4cOHgSOLEjlzRZWUJUuWsHTpUuBIw75z/caNG7No0SKS\nk5P57bff/I77+OOPmT179lFdM1yciRC3bdvm7gs2sLG02hliYuzPN9R8W8YYZs+eHdb1vvzySxo3\nbkzLli1p2LBhRAV23LhxfPbZZzRo0IDPP/88YteJJtu3b6ddu3bcc8890TalxKgolAL9+vXj0ksv\nBfznQerUqVNYL4UxhqFDh3LLLbeEzBOOKDh5vKKwa9cuN/3xxx93vzsFV7C2B2MMS5cuLXY8hdcO\nx3tJTU117fB6NI4YeGuHXlEJl9NPP52zzz4bOFIoOmRlZTFnzhwWLVrENddc45d23XXXce6554Y8\n74IFC+jYsSNbt271279371769etXZJjPIdjsuIGeQk5ODpmZmX77jqb9B3B7m2VlZQUt+P/73/9y\n7rnn8s477xR7rlmzZgG2rQMo9BwCWb9+vSvOJWHXrl1cf/31rqfoXDeSzJ07lzPPPLNUhe6nn35i\n7NixIdOdd//NN98E7PM8XgatqiiUMl5PoXbt2pxzzjnFHjN27Fj+85//uGGjxMREt2bt8K9//YtR\no0YBxYuCN9Ye2E31wQcfZMWKFe52sBp7RkYGHTp0cOdxCkUwUTh8+LAbgvKKgtOo6g1NeAVi4sSJ\njBgxAoC77rqLhg0bAviJWiAxMTH8/PPPfgWi89wyMjJYvnw51157rV+jfjAhmj9/PnfeeSe//fYb\nn332mV/ae++9x6RJk3j++efdfT/++CMiwty5czHGkJOTw6OPPsrq1asLnTs2NpbMzExOPfVUFi5c\nSLt27WjQoIFfnnA6HQTDeX5paWnExMQUaltYvHixe3/FEShogcIVSNu2benQoUOJvZ7Aew1sg3P4\n+9//zhdffFGic4diyJAhzJs3z30eBw4cOGaB6NWrF4MHD3a3f/vtN3r27MmBAweAI7/F/Px8duzY\nQePGjXnyySfDOvePP/4Y1bXfozYh3omKVxTq1KnjxtqD0bp1azIyMgqNiN67d2+heOvbb78N2BrH\nwoULg57PCR85f0Wk0I97+PDhfPvtt+72W2+9Veg8oXrMBOINW3zzzTe0atWKtWvXMn/+fM4++2z2\n79+PiGCMCeopbNu2jWbN7PRY/fvbWdXvv/9+N9w2ffp0evTowX/+85+gDfbr16+ne/fu7jkAt2De\nv38/7du3xxjDTTfd5KYH/ti+/fZbLr74Ynd7xowZQb07b+E3cuRIAM466yzOOeccEhMTmTx5ctC1\nNnJzc/nwww9JT09n9OjRhdpxwApmSef0ysvLK9RYP2fOHL+BjoHvA9hCKpidRYlCZmYmGzduZPr0\n6axatYoRI0a43s369esLhSGLIrDHVTBRKCgo4LnnngNKJ9TmvHOOEDRv3pzs7Oyj8lRDcf/99zNt\n2jR++OEHPvzwQ79nMn36dMC+W8WRmZlJ7969GT58OPfff3+p2VcS1FMoZbwvee3atYsUhcTERDd/\n/fr1/dKcQjKQ559/PuTyn8HCNsEGtHlra86Pz8vXX3/tfg/0WLwEFrCnnHIKSUlJbs30999/d2e1\nDeYpeGPvDk5jLcA//vEPwHpJEDrMsmnTkRnalyxZ4n53ChRv+4LX5ry8PD788EO/czmCW1SB4bVj\n9uzZbntSsEbFAwcOuIV3hw4dgp7PEcySMGbMGPe6DoFtC06t1fkLob3MwFCc9705++yzSUlJYdiw\nYbz++uuMHz/eTQunoPMSKAr5+fns27ePe+65h82b7XyZwd6Lo22UzsvLc8/n3NOuXbs4fPiwX1tX\ncWzatInevXuH/F85ojp8+HAmTJjg13PQ+T9VqlQJEeGHH34IeZ3169djjDnqNrfSQEWhlPF6CgkJ\nCW4DbDASExPdUE9ggRGOyx/IxIkTGTVqlCsK+fn5vPvuu4XyFfcD8xas27dvZ+nSpfz000/uvpEj\nR9K7d2/uuOMOv+Pi4+NJTk523fT9+/e7tfi+ffsycOBAxo8f74aGnB+rt6CaMGGC+33mzJmAjXPn\n5ub6FW6h8I4FcfC2jQSGvJYt81sIkI0bN/Ljjz8SFxfH3Llz3TiwtyYdbkECtvB2BhcG2v/vf/8b\nKFxQFhQUsHv3bhYuXBiy626wQiMwNON4CN7ze3uCeQkUQa+n4HRndjwMr02ff/65XzfkdevWFaq0\nFBQU8PTTT3PHHXcU8kyzs7O54YYbGD16tFsZCQyDTZ06lQYNGvDdd9+5+2bOnMm2bdt48803SU9P\nZ/Dgwe57n5aWxssvv8zzzz/PY4895ndPXkGvWbOmn5dYFM899xw//PADH330UZHhPudZeSsIzu/B\n8Ri8YafDhw8zadIkd9up4AQK44EDB4KKZUQwxhxXny5dupjyzOLFiw1g7KM1ZtWqVe524Ofqq682\nNWrUMIC55557DGBat25thg8fHvIY51O3bt2QaQ8//LDfdnx8vBk9enSx5wz2SU1N9buf33//PWTe\nm2++2dxwww2mVatWZuTIkQYwAwcOLJTvD3/4gwHMM888Y4wxZt68eW7aKaecYk477TTz5Zdfmrff\nftv84x//MIBZt26d2bx581Hdg/czc+ZM9/vGjRtN27Zt3e2OHTsawFxzzTUGMM8995x5/PHH3fTk\n5GTz+OOPm+7dux/VtW+77Ta/7U8++cQA5oMPPnDfn/z8fJOSkmKqV6/u99znzp1rJk+e7OZ74okn\nDGDOPfdcN1/btm3NgAEDzOHDh40xxn3O3s+iRYuCvreDBw8ulHft2rXmyy+/LLS/a9euhfYZY8w/\n//lPv+fssGDBgiKfifMbePXVV40xxrz//vtuekFBgbn99tsNYEaNGmW2b99uEhISgp7rtddeM8YY\nv/RatWq53x9//HHz2muvBbXdYf/+/ea6664zXbt2NatWrXL3O7/PESNG+N2P86wvvPBCA5iqVasW\nOn+9evVCXvPBBx/0e14jRowwgOndu7cxxphly5aZAwcOmCuvvNIA5tChQ8UVQSEB0kwYZax6CqWM\nEw5yPIbiwkdOjSI5ORmwsckHHnig2OsU5YEE1mSmTJlSKDxVHElJSYB/L5R9+/b5hWoCyc3NpXr1\n6uzbt8+NhzZp0qRQvo4dO1KnTh2+/vpr7r33Xj744AM3LT09na5du9K/f39uvfVWLrjgAsB6C06N\nOxROTdY79ciNN97ol8frKWRnZ/s1ZJ9++ukAbkP8gQMH/J7lwoULeeaZZ/w8hdatWxdpk5fAhmgn\n7uytyX/zzTekpaUV8iq6devGZZdd5md7zZo1/eLOK1eu5OOPP3bbn4LN3ut4GMuXL+f2229nxIgR\nFBQUBPUgWrVqFbR7tDfE55CVlcXf//53d9vr8RXlmW7fvt2N9b/99tukp6f7zQrctm1btx2mevXq\nzJo1K2QX3PT0dFJTU/16+ezbt49OnTqRlJREZmYmd911V0hbADc8Nm/ePP71r3+xfft2RMTtNp6f\nn+8XXg2cGiZY2DFYo70TIXDCbxs3bvT7u23bNnbv3k27du24/fbb3XZAr8ceKVQUShmnsL7vvvv8\ntoPRpEkTVxSaNWtGQUGB28hZ3KCnosTG25jZoUMHzj33XNq3b++Xp0qVKkV2BzzrrLMA/3BMenq6\n+9J6ef311wFbiNaoUcOvoA12/23btqVhw4bMnTuXV1991e1V5eBtOHbaJB577DEefPDBkPYCdOnS\nBbAN/M51AwfteUUhKyvLL0bcsWNH4EgbxJo1a4LGkL3PxLGvbt26fnmC2RoYEvS2t/zyyy8UFBTw\n0ksvkZSU5Nc2FUwMs7OziY+PD/p8Z8yYwaFDh/x62Nx5553AkbaqV199lbfeeos///nPLF682K+g\n9RbuwQgmIFOmTPHbdioT33zzjd/YlUB+/fVX9/uCBQto3769nyisXr3aDcns27eP6tWrhzzXyJEj\n6datG4cPH2bgwIHuO1yzZk3q1asXMvxy1113sWLFCowxfPLJJ7Rv355bb72VsWPHul2bnYkpV6xY\nwSuvvOIe6+3UURJGjx7Np59+6gqGc36n0rVx40auv/56wIbonHd74sRCE0yXOioKpUyDBg3YtGmT\n2zga2LuiadOm7Ny5k59++onHHnvMFYWEhAS/F6tWrVpFXqdhw4aMGTOGH3/8sVA3Sm/vImduJu8c\nTWALZm+NOnCQlZPfO9r6k08+Cdqw6JwnJyfHnUHWoWbNmoXyN23a1G1XcOjRo4dfuoMjEOEMPDvl\nlFMAW2A6BW6dOnX88lx77bXu982bN/t13+3ataufXatWrSq2u6gjBmeccYbf/ttvv71Q3qysLBo1\nasR9991HtWrVqF27NrVq1WLcuHGcc845VKpUienTpzNs2DC/XkTXXXed+z07O5vc3FxXFIK9J+PG\njaN69ep+Be75559Pz549ycvLY8+ePX5x+507d/oV9M8++6zf/6C4ewfreYgIOTk5XHDBBWzdupWf\nf/6ZK664ghdeeCHo8TVq1Cg0/iM/P7/Q+iGOrenp6YXaX5wBol7y8vLo0aOH+7+vWbMmHTp04Msv\nvwTgvPPO88s/ZswYLr74Yp5++mnmzJlDv3793EI4cJqSN998k0OHDrmjyINNIhmOQNx3331cc801\n7riQZ599lp49e7qVrqysLNc7Ads+17BhQ4YPH17suY8VFYUI0LRpU/fFCPaC1K1blx49elClShW3\n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\nrkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x1173b7630>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.plot(loss_vec, 'k-', label='Train Loss')\n",
    "plt.plot(test_loss, 'r--', label='Test Loss')\n",
    "plt.title('Loss (MSE) per Generation')\n",
    "plt.xlabel('Generation')\n",
    "plt.ylabel('Loss')\n",
    "plt.legend(loc='upper right')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
